using Palmmedia.ReportGenerator.Core;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class RLTorchController : MonoBehaviour
{
    public Pid ShowPid;
    public RobotCreator rc;
    public Vector2 PRange;
    public Vector2 IRange;
    public Vector2 DRange;
    public Vector2 Delta_PRange;
    public Vector2 Delta_IRange;
    public Vector2 Delta_DRange;
    public Text generation;
    public int size = 100;
    public float hard = 0;
    private RLTorch[] Qtable;
    
    public RLTorch CreateInitRLTorch()
    {
        var res=new RLTorch(0, new Vector3(Random.Range(PRange.x, PRange.y), 
            Random.Range(IRange.x, IRange.y), 
            Random.Range(DRange.x, DRange.y)),
            new Vector3(Random.Range(Delta_PRange.x, Delta_PRange.y),
            Random.Range(Delta_IRange.x, Delta_IRange.y), 
            Random.Range(Delta_DRange.x, Delta_DRange.y)));
        Debug.Log(res);
        return res;
    }
    IEnumerator main()
    {
        for (int j = 0; j < 10; j++)
        {
            generation.text=(j+1).ToString();
            rc.Create(size);
            yield return new WaitForSeconds(1f);
            SetHard();
            rc.ChangePid(Qtable);
            rc.Unlock();
            float start_time = Time.time;
            float[] score = new float[size];
            for (int i = 0; i < size; i++)
            {
                score[i] = 30;
            }

            while (Time.time- start_time < 30)
            {
                for (int i = 0; i < size; i++)
                {
                    if (rc.robots[i] == null && score[i] == 30)
                    {
                        score[i] = Time.time - start_time;
                        Debug.Log($"{i} is dead,score is {score[i]}");

                    }

                }
                yield return new WaitForSeconds(0.02f);
            }
            for (int i = 0; i < size; i++)
            {
                if (rc.robots[i] != null)
                {
                    Destroy(rc.robots[i]);
                }
            }
            rc.robots=new();
            for (int i = 0; i < size; i++)
            {
                Qtable[i].QValue=score[i];
                Debug.Log($"{i}score is {score[i]}");
            }
            yield return new WaitForSeconds(1f);
            UpdateQtable(ref Qtable);
        }
        yield return 0;
    }
    private void Start()
    {
        Qtable = new RLTorch[size];
        for (int i = 0; i < size; i++)
        {
            Qtable[i] = CreateInitRLTorch();
        }
        StartCoroutine(main());
    }
    private void SetHard()
    {
        hard += 0.5f + hard * 2;
        if (hard > 5)
        {
            hard = 5;
        }
       
       foreach(var robot in rc.robots)
        {

            robot.GetComponentInChildren<VirturalInput>().random_val = hard;
        }
    }
    public void UpdateQtable(ref RLTorch[] q_table)
    {
        RLTorch max_q_torch=new RLTorch(-1,Vector3.zero,Vector3.zero);
        for(int i = 0;i < size; i++)
        {
            if (q_table[i].QValue >=max_q_torch.QValue)
            {
                if (Mathf.Abs(q_table[i].QValue - max_q_torch.QValue) < 1 && q_table[i].GetNewPid().x> max_q_torch.GetNewPid().x)
                {
                    break;
                }
                max_q_torch = q_table[i];
            }
        }
        ShowPid.kp = max_q_torch.PidValue.x;
        ShowPid.ki = max_q_torch.PidValue.y;
        ShowPid.kd = max_q_torch.PidValue.z;
        for (int i = 0; i < size; i++)
        {
            q_table[i] = new RLTorch(max_q_torch);
            q_table[i].QValue = 0;
            q_table[i].PidValue = q_table[i].GetNewPid();
            q_table[i].PidDelta = new Vector3(Random.Range(Delta_PRange.x, Delta_PRange.y),
            Random.Range(Delta_IRange.x, Delta_IRange.y),
            Random.Range(Delta_DRange.x, Delta_DRange.y));
            Debug.Log(q_table[i]);
        }

    }
    
}
